{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "-578TXDLZF47"
   },
   "outputs": [],
   "source": [
    "# Run this to install tensorflow version 1.9\n",
    "# !pip install -q tensorflow==1.9\n",
    "# Make sure you RESTART RUNTIME (Runtime->Restart Runtime) after running this"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 51
    },
    "colab_type": "code",
    "id": "HnA-Zf8JqsL4",
    "outputId": "f1b799cb-e735-4c19-e59d-254b99c627d5"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Gym: 0.10.11\n"
     ]
    }
   ],
   "source": [
    "import gym\n",
    "import random\n",
    "import numpy as np\n",
    "print(\"Gym:\", gym.__version__)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 51
    },
    "colab_type": "code",
    "id": "YHkYC1tmqsMB",
    "outputId": "27b9c0d6-bc0f-426c-9bdb-b791aba2a60e"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Observation space: Box(3,)\n",
      "Action space: Box(1,)\n"
     ]
    }
   ],
   "source": [
    "env_name = \"Pendulum-v0\"\n",
    "# env_name = \"MountainCarContinuous-v0\"\n",
    "# env_name = \"LunarLanderContinuous-v2\"\n",
    "env = gym.make(env_name)\n",
    "print(\"Observation space:\", env.observation_space)\n",
    "print(\"Action space:\", env.action_space)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Tensorflow QNetwork\n",
    "\n",
    "Below is the implementation of an Actor Critic network using tensorflow as the backend model. This contains a tensorflow session and after initially building the network graph, it is trained by running the optimizer with the state, action for accessing the action and q values and the next_state, reward and done for calculating the q_target values for training."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "79GCjcYYqsMG"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tensorflow: 1.9.0\n"
     ]
    }
   ],
   "source": [
    "import tensorflow as tf\n",
    "print(\"Tensorflow:\", tf.__version__)\n",
    "\n",
    "class TFACNetwork():\n",
    "    def __init__(self, state_size, action_size, action_range):\n",
    "        tf.reset_default_graph()\n",
    "        self.state_in = tf.placeholder(tf.float32, shape=[None, state_size])\n",
    "        self.action_in = tf.placeholder(tf.float32, shape=[None, action_size])\n",
    "        self.next_state_in = tf.placeholder(tf.float32, shape=[None, state_size])\n",
    "        self.reward_in = tf.placeholder(tf.float32, shape=[None])\n",
    "        self.done_in = tf.placeholder(tf.float32, shape=[None])\n",
    "\n",
    "        self.action_low, self.action_high = action_range\n",
    "        self.actor_local = self.build_actor(action_size, scope=\"actor_local\")\n",
    "        self.actor_target = self.build_actor(action_size, scope=\"actor_target\")\n",
    "        self.critic_local = self.build_critic(self.state_in, self.action_in, scope=\"critic_local\")\n",
    "        self.critic_target = self.build_critic(self.next_state_in, self.actor_target, scope=\"critic_target\")\n",
    "\n",
    "        self.optimizer = self.build_optimizer()\n",
    "        self.updater = self.build_updater()\n",
    "        \n",
    "        self.sess = tf.Session()\n",
    "        self.sess.run(tf.global_variables_initializer())\n",
    "          \n",
    "    def build_actor(self, action_size, scope=None):\n",
    "        with tf.variable_scope(scope):\n",
    "            layer1 = tf.layers.dense(self.state_in, 100, activation=tf.nn.relu)\n",
    "            layer2 = tf.layers.dense(layer1, 100, activation=tf.nn.relu)\n",
    "            layer3 = tf.layers.dense(layer2, 100, activation=tf.nn.relu)\n",
    "            action_raw = tf.layers.dense(layer3, action_size, activation=None)\n",
    "            action_scaled = self.action_low + (self.action_high - self.action_low) * tf.nn.sigmoid(action_raw)\n",
    "            return action_scaled\n",
    "\n",
    "    def build_critic(self, state, action, scope=None, reuse=False):\n",
    "        with tf.variable_scope(scope):\n",
    "            net_state = tf.layers.dense(state, 100, activation=tf.nn.relu, reuse=reuse, name=\"critic1\")\n",
    "            net_action = tf.layers.dense(action, 100, activation=tf.nn.relu, reuse=reuse, name=\"critic2\")\n",
    "            net_state_action = tf.concat([net_state, net_action], axis=1)\n",
    "            net_layer = tf.layers.dense(net_state_action, 100, activation=tf.nn.relu, reuse=reuse, name=\"critic3\")\n",
    "            q_value = tf.layers.dense(net_layer, 1, activation=None, reuse=reuse, name=\"critic4\")\n",
    "            return q_value\n",
    "        \n",
    "    def build_updater(self, tau=0.01):\n",
    "        actor_update_ops = [tf.assign(t, t+tau*(l-t)) for l,t in zip(self.get_vars(\"actor_local\"), self.get_vars(\"actor_target\"))]\n",
    "        critic_update_ops = [tf.assign(t, t+tau*(l-t)) for l,t in zip(self.get_vars(\"critic_local\"), self.get_vars(\"critic_target\"))]\n",
    "        updater = tf.group(*actor_update_ops, *critic_update_ops)\n",
    "        return updater\n",
    "        \n",
    "    def build_optimizer(self, learn_rate=0.00025, gamma=0.97):\n",
    "        rewards = tf.expand_dims(self.reward_in, axis=1)\n",
    "        dones = tf.expand_dims(self.done_in, axis=1)\n",
    "        q_targets = rewards + gamma * self.critic_target * (1-dones)\n",
    "        critic_error = q_targets - self.critic_local\n",
    "        critic_loss = tf.reduce_mean(tf.square(critic_error))\n",
    "        critic_optimizer = tf.train.AdamOptimizer(learn_rate).minimize(critic_loss, var_list=self.get_vars(\"critic_local\"))\n",
    "        \n",
    "        actor_trainer = self.build_critic(self.state_in, self.actor_local, scope=\"critic_local\", reuse=True)\n",
    "        actor_gain = tf.reduce_mean(actor_trainer - self.critic_local)\n",
    "        actor_optimizer = tf.train.AdamOptimizer(learn_rate).minimize(-actor_gain, var_list=self.get_vars(\"actor_local\"))\n",
    "        \n",
    "        optimizer = tf.group(actor_optimizer, critic_optimizer)\n",
    "        return optimizer\n",
    "        \n",
    "    def get_vars(self, scope):\n",
    "        return tf.get_collection(tf.GraphKeys.TRAINABLE_VARIABLES, scope=scope)\n",
    "    \n",
    "    def update_model(self, state, action, next_state, reward, done):\n",
    "        feed = {self.state_in: state, self.action_in: action, self.next_state_in: next_state, self.reward_in: reward, self.done_in: done}\n",
    "        self.sess.run([self.optimizer, self.updater], feed_dict=feed)\n",
    "        \n",
    "    def get_action(self, state):\n",
    "        action = self.sess.run(self.actor_local, feed_dict={self.state_in: state})\n",
    "        return action\n",
    "    \n",
    "    def __del__(self):\n",
    "        self.sess.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Pytorch QNetwork\n",
    "\n",
    "Below is the implementation of an Actor Critic network using pytorch as the backend model. This involves first defining a Model class for both the Actor and Critic which subclasses the pytorch nn.Module class and then defines the network graph which can be run with the forward function.\n",
    "\n",
    "Then the Model is included in an enclosing PTQNetwork class which trains the model by taking in the states and running the Model class to get the q values which are then indexed by the actions and then the gradients are calculated from the MSE loss between the predicted q value and the q_target."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Torch: 1.0.1.post2\n"
     ]
    }
   ],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "import torch.optim as optim\n",
    "print(\"Torch:\", torch.__version__)\n",
    "\n",
    "class Actor(nn.Module):\n",
    "    def __init__(self, state_size, action_size, action_range):\n",
    "        super().__init__()\n",
    "        self.action_low, self.action_high = torch.from_numpy(np.array(action_range))\n",
    "        self.layer1 = nn.Linear(state_size, 100)\n",
    "        self.layer2 = nn.Linear(100, 100)\n",
    "        self.layer3 = nn.Linear(100, 100)\n",
    "        self.action = nn.Linear(100, action_size)\n",
    "\n",
    "    def forward(self, state):\n",
    "        layer1 = F.relu(self.layer1(state))\n",
    "        layer2 = F.relu(self.layer2(layer1))\n",
    "        layer3 = F.relu(self.layer3(layer1))\n",
    "        action = torch.sigmoid(self.action(layer3))\n",
    "        return self.action_low + (self.action_high-self.action_low)*action\n",
    "    \n",
    "class Critic(nn.Module):\n",
    "    def __init__(self, state_size, action_size):\n",
    "        super().__init__()\n",
    "        self.net_state = nn.Linear(state_size, 100)\n",
    "        self.net_action = nn.Linear(action_size, 100)\n",
    "        self.net_layer = nn.Linear(200, 100)\n",
    "        self.q_value = nn.Linear(100, 1)\n",
    "\n",
    "    def forward(self, state, action):\n",
    "        net_state = F.relu(self.net_state(state))\n",
    "        net_action = F.relu(self.net_action(action))\n",
    "        net_state_action = torch.cat([net_state, net_action], dim=1)\n",
    "        net_layer = F.relu(self.net_layer(net_state_action))\n",
    "        q_value = self.q_value(net_layer)\n",
    "        return q_value\n",
    "\n",
    "class PTACNetwork():\n",
    "    def __init__(self, state_size, action_size, action_range): \n",
    "        self.actor_local = Actor(state_size, action_size, action_range)\n",
    "        self.actor_target = Actor(state_size, action_size, action_range)\n",
    "        self.actor_optimizer = optim.Adam(self.actor_local.parameters(), lr=0.00025)\n",
    "        \n",
    "        self.critic_local = Critic(state_size, action_size)\n",
    "        self.critic_target = Critic(state_size, action_size)\n",
    "        self.critic_optimizer = optim.Adam(self.critic_local.parameters(), lr=0.00025)\n",
    "        \n",
    "    def get_action(self, state):\n",
    "        state = torch.from_numpy(np.array(state)).float()\n",
    "        action = self.actor_local(state).detach().numpy()\n",
    "        return action\n",
    "    \n",
    "    def update_model(self, state, action, next_state, reward, done, gamma=0.97):\n",
    "        states = torch.from_numpy(np.vstack(state)).float()\n",
    "        actions = torch.from_numpy(np.vstack(action)).float()\n",
    "        next_states = torch.from_numpy(np.vstack(next_state)).float()\n",
    "        rewards = torch.from_numpy(np.vstack(reward)).float()\n",
    "        dones = torch.from_numpy(np.vstack(done)).float()\n",
    "        next_actions = self.actor_local(next_states)\n",
    "        \n",
    "        q_targets = rewards + gamma * self.critic_target(next_states, next_actions).detach() * (1-dones)\n",
    "        critic_loss = F.mse_loss(self.critic_local(states, actions), q_targets)\n",
    "        self.critic_optimizer.zero_grad()\n",
    "        critic_loss.backward()\n",
    "        self.critic_optimizer.step()\n",
    "        \n",
    "        q_baseline = self.critic_local(states, actions).detach()\n",
    "        actor_gain = -(self.critic_local(states, self.actor_local(states)) - q_baseline)\n",
    "        self.actor_optimizer.zero_grad()\n",
    "        actor_gain.mean().backward()\n",
    "        self.actor_optimizer.step()\n",
    "        \n",
    "        self.soft_copy(self.actor_local, self.actor_target)\n",
    "        self.soft_copy(self.critic_local, self.critic_target)\n",
    "        \n",
    "    def soft_copy(self, local, target, tau=0.01):\n",
    "        for t,l in zip(target.parameters(), local.parameters()):\n",
    "            t.data.copy_(t.data + tau*(l.data - t.data))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Experience Replay\n",
    "Below is the implementation of a Replay Buffer using the deque collection as the rolling buffer of experience tuples. This can be sampled by specifying the sample size and then returns each individual experience type as separate lists."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "EYKcRk3ZqsMJ"
   },
   "outputs": [],
   "source": [
    "from collections import deque\n",
    "import random\n",
    "\n",
    "class ReplayBuffer():\n",
    "    def __init__(self, maxlen):\n",
    "        self.buffer = deque(maxlen=maxlen)\n",
    "        \n",
    "    def add(self, experience):\n",
    "        self.buffer.append(experience)\n",
    "        \n",
    "    def sample(self, batch_size):\n",
    "        sample_size = min(len(self.buffer), batch_size)\n",
    "        samples = random.choices(self.buffer, k=sample_size)\n",
    "        return map(list, zip(*samples))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Exploration Noise\n",
    "Below is the noise process class for exploration of continuous action spaces where noise applied to the action vector varies randomly with inertia from the previous time step."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "class OUNoise():\n",
    "    def __init__(self, size, scale, mu=0.0, sigma=0.4, theta=0.15, decay=0.99):\n",
    "        self.noise = np.zeros(size)\n",
    "        self.size = size\n",
    "        self.scale = scale\n",
    "        self.mu = mu\n",
    "        self.sigma = sigma\n",
    "        self.theta = theta\n",
    "        self.decay = decay\n",
    "    \n",
    "    def reset(self):\n",
    "        self.noise = np.zeros(self.size)\n",
    "        self.scale *= self.decay\n",
    "        \n",
    "    def sample(self):\n",
    "        sample = self.theta * (self.mu - self.noise) + self.sigma * np.random.randn(self.size)\n",
    "        self.noise = sample * self.scale\n",
    "        return self.noise"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Agent\n",
    "Below is the implementation of the agent that uses Deep Actor Critic networks to learn the best action for a given state such that it achieves a reward is better than the critic's estimated value of it. It selects an action from the actor model which then explores by adding a noise process to it which decays over time."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "XKIXlcQSqsMN"
   },
   "outputs": [],
   "source": [
    "class ActorCriticAgent():\n",
    "    # Initializing the agent and the model for selecting actions\n",
    "    def __init__(self, env, network=TFACNetwork):\n",
    "        # The number of state values in the state vector\n",
    "        state_size = np.prod(env.observation_space.shape)\n",
    "        # The number of action indices to select from\n",
    "        action_size = np.prod(env.action_space.shape)\n",
    "        # The continuous range of the actions\n",
    "        action_range = [env.action_space.low, env.action_space.high]\n",
    "        # Defining the q network to use for modeling the Bellman equation\n",
    "        self.q_network = network(state_size, action_size, action_range)\n",
    "        # Defining the replay buffer for experience replay\n",
    "        self.replay_buffer = ReplayBuffer(100000)\n",
    "        # Initializing the epsilon value to 1.0 for initial exploration\n",
    "        self.noise_process = OUNoise(action_size, action_range[1]-action_range[0])\n",
    "        \n",
    "    # Function for getting an action to take in the given state\n",
    "    def get_action(self, state):\n",
    "        # Get the action from the network and add noise to it\n",
    "        return self.q_network.get_action([state])[0] + self.noise_process.sample()\n",
    "        \n",
    "    # Function for training the agent at each time step\n",
    "    def train(self, state, action, next_state, reward, done, batch_size=100):\n",
    "        # First add the experience to the replay buffer\n",
    "        self.replay_buffer.add((state, action, next_state, reward, done))\n",
    "        # Sample a batch of each experience type from the replay buffer\n",
    "        states, actions, next_states, rewards, dones = self.replay_buffer.sample(batch_size)\n",
    "        # Train the model with the q target\n",
    "        self.q_network.update_model(states, actions, next_states, rewards, dones)\n",
    "        # Decrease epsilon after each episode\n",
    "        if done: self.noise_process.reset()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### Training\n",
    "Below is the training loop for training the agent through a number of episodes of interacting with the environment. It keeps track of the total reward from each episode and also stores the last 100 episode rewards for calculating the average reward for checking when the environment was solved."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "colab": {
     "base_uri": "https://localhost:8080/",
     "height": 3434
    },
    "colab_type": "code",
    "id": "zv9Amjj4qsMQ",
    "outputId": "92eeb722-4e00-4c1b-bd4d-63aa795954f1"
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Episode: 0, Score: -1546.5483842697358, Avg reward: -1546.55\n",
      "Episode: 1, Score: -1286.9720393283922, Avg reward: -1416.76\n",
      "Episode: 2, Score: -1261.6922005796862, Avg reward: -1365.07\n",
      "Episode: 3, Score: -1797.393411284232, Avg reward: -1473.15\n",
      "Episode: 4, Score: -1902.7486798548484, Avg reward: -1559.07\n",
      "Episode: 5, Score: -1892.7630286312149, Avg reward: -1614.69\n",
      "Episode: 6, Score: -1800.62212022444, Avg reward: -1641.25\n",
      "Episode: 7, Score: -1814.6209496227882, Avg reward: -1662.92\n",
      "Episode: 8, Score: -1497.705656475965, Avg reward: -1644.56\n",
      "Episode: 9, Score: -1478.5342697630344, Avg reward: -1627.96\n",
      "Episode: 10, Score: -1526.6375515321818, Avg reward: -1618.75\n",
      "Episode: 11, Score: -1398.170535876534, Avg reward: -1600.37\n",
      "Episode: 12, Score: -1356.9298570961143, Avg reward: -1581.64\n",
      "Episode: 13, Score: -1160.8131515031794, Avg reward: -1551.58\n",
      "Episode: 14, Score: -1302.9492012144838, Avg reward: -1535.01\n",
      "Episode: 15, Score: -1350.8417609896812, Avg reward: -1523.50\n",
      "Episode: 16, Score: -1512.460515734979, Avg reward: -1522.85\n",
      "Episode: 17, Score: -1496.116010107917, Avg reward: -1521.36\n",
      "Episode: 18, Score: -1536.1550688676869, Avg reward: -1522.14\n",
      "Episode: 19, Score: -1362.7339532071544, Avg reward: -1514.17\n",
      "Episode: 20, Score: -1233.1772891727537, Avg reward: -1500.79\n",
      "Episode: 21, Score: -1502.0365317843093, Avg reward: -1500.85\n",
      "Episode: 22, Score: -1366.501207561191, Avg reward: -1495.01\n",
      "Episode: 23, Score: -1352.6625750659778, Avg reward: -1489.07\n",
      "Episode: 24, Score: -1399.8731095351598, Avg reward: -1485.51\n",
      "Episode: 25, Score: -1130.3550404467028, Avg reward: -1471.85\n",
      "Episode: 26, Score: -1403.0527983187123, Avg reward: -1469.30\n",
      "Episode: 27, Score: -1290.4160958922052, Avg reward: -1462.91\n",
      "Episode: 28, Score: -1362.4345549036232, Avg reward: -1459.45\n",
      "Episode: 29, Score: -1202.5926747493636, Avg reward: -1450.88\n",
      "Episode: 30, Score: -1467.4385769606272, Avg reward: -1451.42\n",
      "Episode: 31, Score: -1325.2360802059843, Avg reward: -1447.47\n",
      "Episode: 32, Score: -1357.9775957373938, Avg reward: -1444.76\n",
      "Episode: 33, Score: -1208.1730374079837, Avg reward: -1437.80\n",
      "Episode: 34, Score: -1342.0617921603828, Avg reward: -1435.07\n",
      "Episode: 35, Score: -1205.139497452969, Avg reward: -1428.68\n",
      "Episode: 36, Score: -1339.2840439980232, Avg reward: -1426.27\n",
      "Episode: 37, Score: -1356.7046779347008, Avg reward: -1424.43\n",
      "Episode: 38, Score: -1326.849483841232, Avg reward: -1421.93\n",
      "Episode: 39, Score: -1339.5406455148134, Avg reward: -1419.87\n",
      "Episode: 40, Score: -1294.4348846247592, Avg reward: -1416.81\n",
      "Episode: 41, Score: -764.5559799170329, Avg reward: -1401.28\n",
      "Episode: 42, Score: -1337.4684925630652, Avg reward: -1399.80\n",
      "Episode: 43, Score: -1432.7927782878833, Avg reward: -1400.55\n",
      "Episode: 44, Score: -668.2954821528673, Avg reward: -1384.28\n",
      "Episode: 45, Score: -1455.58487673257, Avg reward: -1385.83\n",
      "Episode: 46, Score: -1364.0986432946315, Avg reward: -1385.36\n",
      "Episode: 47, Score: -1324.1658196415758, Avg reward: -1384.09\n",
      "Episode: 48, Score: -1349.8667718724187, Avg reward: -1383.39\n",
      "Episode: 49, Score: -1309.9757785349964, Avg reward: -1381.92\n",
      "Episode: 50, Score: -844.2551010277248, Avg reward: -1371.38\n",
      "Episode: 51, Score: -766.4845505226044, Avg reward: -1359.75\n",
      "Episode: 52, Score: -1227.0941177202535, Avg reward: -1357.25\n",
      "Episode: 53, Score: -1243.0580840250352, Avg reward: -1355.13\n",
      "Episode: 54, Score: -1331.1978761538815, Avg reward: -1354.70\n",
      "Episode: 55, Score: -1303.4353374674588, Avg reward: -1353.78\n",
      "Episode: 56, Score: -983.3113350146865, Avg reward: -1347.28\n",
      "Episode: 57, Score: -980.3495342082309, Avg reward: -1340.95\n",
      "Episode: 58, Score: -1343.373508889935, Avg reward: -1341.00\n",
      "Episode: 59, Score: -1354.6039185634916, Avg reward: -1341.22\n",
      "Episode: 60, Score: -910.0771176903162, Avg reward: -1334.15\n",
      "Episode: 61, Score: -1023.7411928020031, Avg reward: -1329.15\n",
      "Episode: 62, Score: -917.3916615610243, Avg reward: -1322.61\n",
      "Episode: 63, Score: -1341.5893407886415, Avg reward: -1322.91\n",
      "Episode: 64, Score: -1017.7482636260602, Avg reward: -1318.21\n",
      "Episode: 65, Score: -999.5990454127574, Avg reward: -1313.39\n",
      "Episode: 66, Score: -1149.3731797262617, Avg reward: -1310.94\n",
      "Episode: 67, Score: -912.4192466818915, Avg reward: -1305.08\n",
      "Episode: 68, Score: -915.6943556260119, Avg reward: -1299.43\n",
      "Episode: 69, Score: -897.7760129574312, Avg reward: -1293.70\n",
      "Episode: 70, Score: -872.4407893698537, Avg reward: -1287.76\n",
      "Episode: 71, Score: -776.6831101724042, Avg reward: -1280.66\n",
      "Episode: 72, Score: -793.1013210417462, Avg reward: -1273.99\n",
      "Episode: 73, Score: -753.7165148898181, Avg reward: -1266.95\n",
      "Episode: 74, Score: -646.8196699919205, Avg reward: -1258.69\n",
      "Episode: 75, Score: -519.8054481353652, Avg reward: -1248.96\n",
      "Episode: 76, Score: -388.71620032828326, Avg reward: -1237.79\n",
      "Episode: 77, Score: -505.2569839930923, Avg reward: -1228.40\n",
      "Episode: 78, Score: -627.1917689046783, Avg reward: -1220.79\n",
      "Episode: 79, Score: -4.279273448313945, Avg reward: -1205.58\n",
      "Episode: 80, Score: -745.896852149167, Avg reward: -1199.91\n",
      "Episode: 81, Score: -768.0065071755862, Avg reward: -1194.64\n",
      "Episode: 82, Score: -780.903778752193, Avg reward: -1189.66\n",
      "Episode: 83, Score: -897.4364041257599, Avg reward: -1186.18\n",
      "Episode: 84, Score: -899.3518788739563, Avg reward: -1182.80\n",
      "Episode: 85, Score: -1472.695836571055, Avg reward: -1186.17\n",
      "Episode: 86, Score: -1028.3106975152734, Avg reward: -1184.36\n",
      "Episode: 87, Score: -1019.4408542481326, Avg reward: -1182.49\n",
      "Episode: 88, Score: -1020.9305623054909, Avg reward: -1180.67\n",
      "Episode: 89, Score: -1018.6375815231575, Avg reward: -1178.87\n",
      "Episode: 90, Score: -1019.2297246210645, Avg reward: -1177.12\n",
      "Episode: 91, Score: -963.9458371128756, Avg reward: -1174.80\n",
      "Episode: 92, Score: -987.4005689667143, Avg reward: -1172.78\n",
      "Episode: 93, Score: -988.9139369358686, Avg reward: -1170.83\n",
      "Episode: 94, Score: -889.5149181294062, Avg reward: -1167.87\n",
      "Episode: 95, Score: -765.9145038026219, Avg reward: -1163.68\n",
      "Episode: 96, Score: -1067.8538212976712, Avg reward: -1162.69\n",
      "Episode: 97, Score: -1067.5849397328452, Avg reward: -1161.72\n",
      "Episode: 98, Score: -1003.1425765476558, Avg reward: -1160.12\n",
      "Episode: 99, Score: -1027.6524415592933, Avg reward: -1158.80\n",
      "Episode: 100, Score: -1062.899805577271, Avg reward: -1153.96\n",
      "Episode: 101, Score: -1096.1462813058233, Avg reward: -1152.05\n",
      "Episode: 102, Score: -1226.0848798079799, Avg reward: -1151.69\n",
      "Episode: 103, Score: -1026.7153748944395, Avg reward: -1143.99\n",
      "Episode: 104, Score: -1070.854447438272, Avg reward: -1135.67\n",
      "Episode: 105, Score: -1090.6295765359241, Avg reward: -1127.65\n",
      "Episode: 106, Score: -1067.2970311509305, Avg reward: -1120.31\n",
      "Episode: 107, Score: -971.5300109606974, Avg reward: -1111.88\n",
      "Episode: 108, Score: -892.8990591900539, Avg reward: -1105.83\n",
      "Episode: 109, Score: -638.3313986737195, Avg reward: -1097.43\n",
      "Episode: 110, Score: -851.9891218034612, Avg reward: -1090.69\n",
      "Episode: 111, Score: -857.8508800161794, Avg reward: -1085.28\n",
      "Episode: 112, Score: -747.3936296357141, Avg reward: -1079.19\n",
      "Episode: 113, Score: -844.405700636038, Avg reward: -1076.02\n",
      "Episode: 114, Score: -881.3291616399185, Avg reward: -1071.81\n",
      "Episode: 115, Score: -634.4381513864153, Avg reward: -1064.64\n",
      "Episode: 116, Score: -1054.666027479188, Avg reward: -1060.07\n",
      "Episode: 117, Score: -602.3271542115244, Avg reward: -1051.13\n",
      "Episode: 118, Score: -506.6630737966598, Avg reward: -1040.83\n",
      "Episode: 119, Score: -492.93620231904816, Avg reward: -1032.13\n",
      "Episode: 120, Score: -374.23255371017353, Avg reward: -1023.55\n",
      "Episode: 121, Score: -127.35696904775999, Avg reward: -1009.80\n",
      "Episode: 122, Score: -248.05962984554307, Avg reward: -998.61\n",
      "Episode: 123, Score: -122.35530526309684, Avg reward: -986.31\n",
      "Episode: 124, Score: -890.6853603116876, Avg reward: -981.22\n",
      "Episode: 125, Score: -239.053372796053, Avg reward: -972.31\n",
      "Episode: 126, Score: -354.3285535099007, Avg reward: -961.82\n",
      "Episode: 127, Score: -440.3240307919672, Avg reward: -953.32\n",
      "Episode: 128, Score: -248.046872175912, Avg reward: -942.17\n",
      "Episode: 129, Score: -0.7517654678513027, Avg reward: -930.16\n",
      "Episode: 130, Score: -240.52205723571336, Avg reward: -917.89\n",
      "Episode: 131, Score: -0.5433903716681199, Avg reward: -904.64\n",
      "Episode: 132, Score: -361.36564624397056, Avg reward: -894.67\n",
      "Episode: 133, Score: -226.46457786689862, Avg reward: -884.86\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Episode: 134, Score: -117.89551883227588, Avg reward: -872.61\n",
      "Episode: 135, Score: -126.12865093474907, Avg reward: -861.82\n",
      "Episode: 136, Score: -123.8423334555315, Avg reward: -849.67\n",
      "Episode: 137, Score: -1.7664710158687005, Avg reward: -836.12\n",
      "Episode: 138, Score: -232.69376297255994, Avg reward: -825.18\n",
      "Episode: 139, Score: -365.57385428318247, Avg reward: -815.44\n",
      "Episode: 140, Score: -373.7173911720495, Avg reward: -806.23\n",
      "Episode: 141, Score: -125.39754072373037, Avg reward: -799.84\n",
      "Episode: 142, Score: -380.30702883661456, Avg reward: -790.27\n",
      "Episode: 143, Score: -363.67616673669977, Avg reward: -779.58\n",
      "Episode: 144, Score: -360.3557793808539, Avg reward: -776.50\n",
      "Episode: 145, Score: -451.94110892316144, Avg reward: -766.46\n",
      "Episode: 146, Score: -131.75783159185698, Avg reward: -754.14\n",
      "Episode: 147, Score: -128.27774020978896, Avg reward: -742.18\n",
      "Episode: 148, Score: -245.66561550207985, Avg reward: -731.14\n",
      "Episode: 149, Score: -123.98247301687626, Avg reward: -719.28\n",
      "Episode: 150, Score: -247.12870422734787, Avg reward: -713.31\n",
      "Episode: 151, Score: -126.05667713232435, Avg reward: -706.90\n",
      "Episode: 152, Score: -245.10080481239686, Avg reward: -697.08\n",
      "Episode: 153, Score: -357.39306661285525, Avg reward: -688.23\n",
      "Episode: 154, Score: -491.77582999173103, Avg reward: -679.83\n",
      "Episode: 155, Score: -239.00202234695448, Avg reward: -669.19\n",
      "Episode: 156, Score: -0.5520212028463567, Avg reward: -659.36\n",
      "Episode: 157, Score: -126.80770242069411, Avg reward: -650.82\n",
      "Episode: 158, Score: -241.14974008689796, Avg reward: -639.80\n",
      "Episode: 159, Score: -349.63283681617395, Avg reward: -629.75\n",
      "Episode: 160, Score: -125.8042202467859, Avg reward: -621.91\n",
      "Episode: 161, Score: -127.59586003311762, Avg reward: -612.95\n",
      "Episode: 162, Score: -249.60086395873705, Avg reward: -606.27\n",
      "Episode: 163, Score: -126.4105484630258, Avg reward: -594.12\n",
      "Episode: 164, Score: -242.04481690548158, Avg reward: -586.36\n",
      "Episode: 165, Score: -359.9464906892134, Avg reward: -579.96\n",
      "Episode: 166, Score: -123.9566583767096, Avg reward: -569.71\n",
      "Episode: 167, Score: -128.24336854246775, Avg reward: -561.87\n",
      "Episode: 168, Score: -375.7758812659241, Avg reward: -556.47\n",
      "Episode: 169, Score: -129.64562567352354, Avg reward: -548.79\n",
      "Episode: 170, Score: -363.3798746087043, Avg reward: -543.70\n",
      "Episode: 171, Score: -250.36806022065534, Avg reward: -538.43\n",
      "Episode: 172, Score: -3.3191309244854432, Avg reward: -530.54\n",
      "Episode: 173, Score: -128.94667466522523, Avg reward: -524.29\n",
      "Episode: 174, Score: -129.01616638474388, Avg reward: -519.11\n",
      "Episode: 175, Score: -1.485886576086483, Avg reward: -513.93\n",
      "Episode: 176, Score: -127.49129056914289, Avg reward: -511.32\n",
      "Episode: 177, Score: -128.71656892623608, Avg reward: -507.55\n",
      "Episode: 178, Score: -125.60263845032618, Avg reward: -502.53\n",
      "Episode: 179, Score: -251.54471173534037, Avg reward: -505.01\n",
      "Episode: 180, Score: -125.04349272311272, Avg reward: -498.80\n",
      "Episode: 181, Score: -125.81700534440178, Avg reward: -492.38\n",
      "Episode: 182, Score: -356.79447444062384, Avg reward: -488.14\n",
      "Episode: 183, Score: -362.19712008886694, Avg reward: -482.78\n",
      "Episode: 184, Score: -125.9672071662607, Avg reward: -475.05\n",
      "Episode: 185, Score: -128.56317905650266, Avg reward: -461.61\n",
      "Episode: 186, Score: -237.91739741423447, Avg reward: -453.70\n",
      "Episode: 187, Score: -2.95196326562149, Avg reward: -443.54\n",
      "Episode: 188, Score: -387.45034612325463, Avg reward: -437.20\n",
      "Episode: 189, Score: -389.35683600103044, Avg reward: -430.91\n",
      "Episode: 190, Score: -127.59791283883632, Avg reward: -422.00\n",
      "Episode: 191, Score: -124.27017446697326, Avg reward: -413.60\n",
      "Episode: 192, Score: -121.94045434694405, Avg reward: -404.94\n",
      "Episode: 193, Score: -127.6442521538705, Avg reward: -396.33\n",
      "Episode: 194, Score: -357.7364336900798, Avg reward: -391.01\n",
      "Episode: 195, Score: -244.6487911337778, Avg reward: -385.80\n",
      "Episode: 196, Score: -127.7381543441927, Avg reward: -376.40\n",
      "Episode: 197, Score: -127.67103261348532, Avg reward: -367.00\n",
      "Episode: 198, Score: -374.4201080584935, Avg reward: -360.71\n",
      "Episode: 199, Score: -404.7064063565095, Avg reward: -354.48\n"
     ]
    }
   ],
   "source": [
    "# Create an agent instance\n",
    "agent = ActorCriticAgent(env, network=PTACNetwork)\n",
    "# Define number of episodes to train for\n",
    "num_episodes = 200\n",
    "# Create a buffer for calculating the last 100 episode average reward\n",
    "scores_buffer = deque(maxlen=100)\n",
    "# List to store each episode's total reward\n",
    "scores = []\n",
    "# List to store the average reward after each episode\n",
    "avg_scores = []\n",
    "\n",
    "# Run the training loop\n",
    "for ep in range(num_episodes):\n",
    "    # Save the initial state\n",
    "    state = env.reset()\n",
    "    # Reset the total reward\n",
    "    total_reward = 0\n",
    "    # Reset the episode terminal condition\n",
    "    done = False\n",
    "    while not done:\n",
    "        # Query the agent for an action to take in the state\n",
    "        action = agent.get_action(state)\n",
    "        # Take the action in the environment\n",
    "        next_state, reward, done, info = env.step(action)\n",
    "        # Train the agent with the new time step experience\n",
    "        agent.train(state, action, next_state, reward, int(done))\n",
    "        # Update the episode's total reward\n",
    "        total_reward += reward             \n",
    "        # Update the current state\n",
    "        state = next_state \n",
    "\n",
    "    # Store the last episode's total reward\n",
    "    scores.append(total_reward)\n",
    "    # Add the total reward to the buffer for calculating average reward\n",
    "    scores_buffer.append(total_reward)\n",
    "    # Store the new average reward\n",
    "    avg_scores.append(np.mean(scores_buffer))\n",
    "    print(\"Episode: {}, Score: {}, Avg reward: {:.2f}\".format(ep, scores[ep], avg_scores[ep]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "JU1OmrO0uHpO"
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.legend.Legend at 0xb2f146128>"
      ]
     },
     "execution_count": 16,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "x = range(len(scores))\n",
    "plt.plot(x, scores, label=\"Scores\")\n",
    "plt.plot(x, avg_scores, label=\"Avg Score\")\n",
    "plt.title(\"Scores\")\n",
    "plt.xlabel(\"Episode\")\n",
    "plt.ylabel(\"Score\")\n",
    "plt.legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "colab": {},
    "colab_type": "code",
    "id": "_UBHQMHzqsMU"
   },
   "outputs": [],
   "source": [
    "env.close()"
   ]
  }
 ],
 "metadata": {
  "colab": {
   "name": "DiscretizedDQNsForContinuousControl.ipynb",
   "provenance": [],
   "version": "0.3.2"
  },
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
